const { Service } = require('egg')
const cheerio = require('cheerio')
const { tableToList } = require('../utils/tools')

// 根据入学年级生成当前学期，year-入学时间，sub-学制
const getTerm = (year, sub) => {
  const t1 = Number(year) + Math.floor((Number(sub) - 1) / 2)
  const t2 = Number(year) + Math.floor((Number(sub) - 1) / 2) + 1
  return `${t1}-${t2}-${Number(sub) % 2 === 0 ? '2' : '1'}`
}

module.exports = class CreditService extends Service {
  /**
   * 学分修读情况
   * @return {Array} *
   */
  async table() {
    // 身份识别信息+学号(获取入学年份),sid-学号
    const Cookie = this.ctx.state.Cookie
    const sid = this.ctx.data.sid
    // 对学号进行处理，得到入学年份
    const year = `20${sid.slice(0, 2)}`
    // 结果保存容器
    const result = []
    // 访问最初的学生完成情况(体系)页面，获取个人识别关键信息ndzydm属性值,ccs-学生完成情况，fir-first
    const ccsFir = `${this.ctx.state.baseUrl}/jsxsd/xxwcqk/xxwcqk_idxOntx.do`

    // 发送请求，获取网页内容
    const resCcs1 = await this.ctx.curl(ccsFir, {
      method: 'GET',
      headers: {
        Cookie,
        // 'Content-Type': 'application/x-www-form-urlencoded',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
      },
      timeout: 10000,
    })
    // 请求状态200检查
    if (resCcs1.status === 200) {
      try {
        // 加载网页内容
        const $ = cheerio.load(resCcs1.data.toString())
        // 从网页内容中寻找到ndzydm属性，获取到其中的value值
        const ndzydm = $('*[name="ndzydm"]').val()
        // console.log('ndzydm', ndzydm)

        // 正式访问学生完成情况(体系)页面，获取到汇总表,ccs-学生完成情况，sec-second
        const ccsSec = `${this.ctx.state.baseUrl}/jsxsd/xxwcqk/xxwcqkOnkctx.do`
        const resCcs2 = this.ctx.curl(ccsSec, {
          method: 'POST',
          headers: {
            Cookie,
            // 'Content-Type': 'application/x-www-form-urlencoded',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
          },
          data: {
            ndzydm, // 关键的身份验证码
            jx0301zxjhid: '',
          },
        })

        // 访问学生成绩表，获取到对应课程的学期,sg-学生成绩,url-网址
        const sgUrl = `${this.ctx.state.baseUrl}/jsxsd/kscj/cjcx_list`
        const sgRes = this.ctx.curl(sgUrl, {
          method: 'POST',
          data: {
            kksj: '',
            kcxz: '',
            kcmc: '',
            xsfs: 'all',
          },
          headers: {
            Cookie,
            'Content-Type': 'application/x-www-form-urlencoded',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
          },
          timeout: 10000,
        })

        // 访问培养计划，获取到未获课程的年份信息，tp-培养计划，url-网址http://jwgl.hutb.edu.cn/jsxsd/pyfa/topyfamx
        const tpUrl = `${this.ctx.state.baseUrl}/jsxsd/pyfa/topyfamx`
        const tpRes = this.ctx.curl(tpUrl, {
          method: 'GET',
          headers: {
            Cookie,
            'Content-Type': 'application/x-www-form-urlencoded',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
          },
        })

        /* 将异步操作完成结果赋值：R1-P1;R2-P2 */
        const [ccs, sg, tp] = await Promise.all([resCcs2, sgRes, tpRes])
        if (ccs.status === 200 && sg.status === 200 && tp.status === 200) {
          // 获取学生每个分类下的汇总信息表格,*-筛选器，全匹配
          const tableCcs = tableToList(ccs.data.toString(), '*')
          // 遍历信息表，整合数据内容
          // 设置细节表
          const detial = { '': [] }// 键与表格向对应
          let detialTable = []// 表格
          const detialHeader = []// 键
          let index = -1// 计数
          tableCcs.forEach((e) => {
            // 如果行的长度等于5，代表是汇总表，删除报告表头行，变量名行，和总计行
            if (e.length === 5 && e[1] !== '' && e[0] !== '总计' && e[0] !== '课程体系(性质)') {
              // 遍历结果表格
              // 设置存储的变量名
              let name = ''
              result.forEach((item) => {
                // 删除除()内的内容之外的重复的键
                if (item.category.replace(/\([^()]*\)/g, '') === e[0].replace(/\([^()]*\)/g, '')) {
                  name = item.category.replace(/\([^()]*\)/g, '')
                  item.category = e[0].replace(/\([^()]*\)/g, '')
                  item.has = ((+item.has) + (+e[2])).toString()
                  item.need = ((+item.need) + (+e[1])).toString()
                }
              })
              if (name !== e[0].replace(/\([^()]*\)/g, '')) {
                result.push({
                  category: e[0],
                  details: [],
                  need: e[1],
                  has: e[2],
                })
              }
            }

            // 如果行的长度等于7，代表是细节表,删除变量名行，和空行
            if (e.length === 7 && e[0] !== '课程编号' && e[0] !== '') {
              // 存储内容
              if (e[1] === '') {
                // 保存变量名，方便后续确定键与内容
                detialHeader.push(e[0])
                if (index++ > -1 && index - 1 >= 0) {
                  // 利用index与变量名列表，达成内容与标题错位的效果
                  detial[detialHeader[index - 1]] = detialTable
                  detialTable = []
                  detial[detialHeader[index]] = detialTable
                }
              } else {
                // 确定内容，删除修读中的信息内容
                if (e[5] !== '修读中') {
                  detialTable.push({
                    N: e[1],
                    T: '',
                    C: e[2],
                    G: e[5],
                    S: '已获',
                  })
                }
                if (e[5] === '修读中') {
                  detialTable.push({
                    N: e[1],
                    T: '',
                    C: e[2],
                    G: '',
                    S: e[5],
                  })
                }
              }
            }
          })

          // 获取培养计划表格
          const tableTp = tableToList(tp.data.toString(), '#mxh')

          // 补充细节表
          // 获取成绩表
          const tableSg = tableToList(sg.data.toString(), '#dataList')
          // 创建detialKey表，以便后续遍历对象
          const detialKey = Object.keys(detial)
          // 遍历成绩表
          tableSg.forEach((sg1) => {
            // 遍历细节表，匹配每一个成绩条
            detialKey.forEach((keys) => {
              // 遍历细节表中每个成绩条;
              detial[keys].forEach((item) => {
                // 判断成绩表课程名字与细节表课程名字是否相同
                if (sg1[3] === item.N) {
                  // 名字相同则将时间添加上
                  item.T = sg1[1]
                }
              })
            })
          })
          // 遍历培养计划表
          tableTp.forEach((tp1) => {
            // 遍历细节表
            detialKey.forEach((keys) => {
              // 遍历细节表中每个成绩条;
              detial[keys].forEach((item) => {
                // 判断成绩表课程名字与细节表课程名字是否相同，开设时间是否为空
                // console.log('tp[3]', tp[3], item.N);
                if (tp1[3] === item.N && item.T === '') {
                  // 名字相同则将时间添加上

                  item.T = getTerm(year, tp1[12])
                }
              })
            })
          })

          // 向result中插入细节表
          result.forEach((e) => {
            if (detial[e.category.replace(/\([^()]*\)/g, '')]) {
              e.details = detial[e.category.replace(/\([^()]*\)/g, '')]
            }
          })
          console.log('result', result)
          return result
        }
        return result
      } catch (err) {
        console.log(err)
      }
      return result
    }
    return result
  }

  /**
   * * 创新学分、素拓分、第二课堂分
   * @return {Array} *
   */
  async extra() {
    const Cookie = this.ctx.state.Cookie
    const apiUrl = `${this.ctx.state.baseUrl}/jsxsd/syjx/getJsonList.do`// http://jwgl.hutb.edu.cn/jsxsd/syjx/getJsonList.do
    const res = await this.ctx.curl(apiUrl, {
      method: 'GET',
      headers: {
        Cookie,
        // 'Content-Type': 'application/x-www-form-urlencoded',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36',
      },
      timeout: 10000,
    })
    const header = ['项目名称', '学分', '类型', '内容', '审核状态']
    const columnNeed = [7, 3, 4, 2, 6]
    // '项目名称'-7, '学分'-3, '类型'-4, '内容'-2, '审核状态'-6
    const result = { table: [], header, has: 0 }

    if (res.status === 200) {
      try {
        const data = JSON.parse(res.data.toString())
        const temp = []
        for (let i = 1; i < data.datZ.length; i++) {
          if (typeof data.datZ[i] !== typeof temp) continue
          if (typeof data.datZ[i] === typeof temp) {
            const tempTable = []
            columnNeed.forEach((idx) => {
              tempTable.push(data.datZ[i][idx])
            })
            if (tempTable[tempTable.length - 1].includes('审核通过')) result.has += Number(tempTable[1])
            temp.push(tempTable)
          }
        }
        result.table = temp
        return result
      } catch (err) {
        return err
      }
    }
    return result
  }
}
